package com.gs.netty.support.codec;


import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;

import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.MessageAggregator;
import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.util.ReferenceCountUtil;

import java.util.List;

/**
 * WebSocketFrameAggregator 对象逻辑改造
 * 改造原因：涉及到数据时候它会把所有的数据都接受完才会执行到下一步。这样就会造成了内存溢出
 */
public class WebSocketStreamFrameAggregator extends MessageAggregator<WebSocketFrame, WebSocketFrame, ContinuationWebSocketFrame, WebSocketFrame> {

    protected WebSocketStreamFrameAggregator(int maxContentLength) {
        super(maxContentLength);
    }

    protected WebSocketStreamFrameAggregator(int maxContentLength, Class<? extends WebSocketFrame> inboundMessageType) {
        super(maxContentLength, inboundMessageType);
    }


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        CodecOutputList out = CodecOutputList.newInstance();
        try {
            if (acceptInboundMessage(msg)) {
                @SuppressWarnings("unchecked")
                WebSocketFrame cast = (WebSocketFrame) msg;
                try {
                    decode(ctx,  cast, out);
                } finally {
                    ReferenceCountUtil.release(cast);
                }
            } else {
                out.add(msg);
            }
        } catch (DecoderException e) {
            throw e;
        } catch (Exception e) {
            throw new DecoderException(e);
        } finally {
            try {
                int size = out.size();
                for (int i = 0; i < size; i++) {
                    ctx.fireChannelRead(out.getUnsafe(i));
                }
            } finally {
                out.recycle();
            }
        }
    }



    @Override
    protected boolean isStartMessage(WebSocketFrame msg) throws Exception {
        return false;
    }

    @Override
    protected boolean isContentMessage(WebSocketFrame msg) throws Exception {
        return false;
    }

    @Override
    protected boolean isLastContentMessage(ContinuationWebSocketFrame msg) throws Exception {
        return false;
    }

    @Override
    protected boolean isAggregated(WebSocketFrame msg) throws Exception {
        return false;
    }

    @Override
    protected boolean isContentLengthInvalid(WebSocketFrame start, int maxContentLength) throws Exception {
        return false;
    }

    @Override
    protected Object newContinueResponse(WebSocketFrame start, int maxContentLength, ChannelPipeline pipeline) throws Exception {
        return null;
    }

    @Override
    protected boolean closeAfterContinueResponse(Object msg) throws Exception {
        return false;
    }

    @Override
    protected boolean ignoreContentAfterContinueResponse(Object msg) throws Exception {
        return false;
    }

    @Override
    protected WebSocketFrame beginAggregation(WebSocketFrame start, ByteBuf content) throws Exception {
        return null;
    }
}
